import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ComponentFixture, fakeAsync, flush, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ButtonModule } from '../button/api';
import { MessageboxModule } from './messagebox.module';
import { MessageboxService } from './messagebox.service';

const CUSTOM_MESSAGE_BOX_CLASS = 'aui-custom-dialog';

@Component({
  template: `
    <button id="confirm" lv-button (click)="confirm()">Confirm</button>
    <button id="info" lv-button (click)="info()">Info</button>
    <button id="success" lv-button (click)="success()">Success</button>
    <button id="warning" lv-button (click)="warning()">Warning</button>
    <button id="error" lv-button (click)="error()">Error</button>
    <button id="danger" lv-button (click)="danger()">Danger</button>
    <button id="custom" lv-button (click)="custom()">Custom</button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
class TestMessageboxComponent {
  lvClass: string = CUSTOM_MESSAGE_BOX_CLASS;

  constructor(private messageBox: MessageboxService) {}

  confirm(): void {
    this.messageBox.confirm('This is a confirm dialog.');
  }

  info(): void {
    this.messageBox.info('This is a info dialog.');
  }

  success(): void {
    this.messageBox.success('This is a success dialog.');
  }

  error(): void {
    this.messageBox.error('This is a error dialog.');
  }

  warning(): void {
    this.messageBox.warning('This is a warning dialog.');
  }

  danger(): void {
    this.messageBox.danger('This is a danger dialog.');
  }

  custom(): void {
    this.messageBox.confirm({
      lvModalKey: 'aui-confirm',
      lvContent: 'This is a confirm dialog.',
      lvClass: this.lvClass,
    });
  }
}

describe('MessageComponent', () => {
  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [TestMessageboxComponent],
      imports: [MessageboxModule, ButtonModule, NoopAnimationsModule],
      teardown: { destroyAfterEach: true },
    }).compileComponents();
  }));

  const getMessageBox = (className: string = '.lv-message-box') => document.querySelector(className);

  describe('basic', () => {
    let fixture: ComponentFixture<TestMessageboxComponent>;

    const openMessagebox = fakeAsync((id: string = 'default', callbck?: () => void) => {
      const button = fixture.nativeElement.querySelector(`#${id}`);
      button.dispatchEvent(new Event('click'));

      tick(1000);
      fixture.detectChanges();
      if (callbck) {
        callbck();
      } else {
        expect(getMessageBox()).toMatchSnapshot();
      }

      document.querySelector('.cdk-overlay-container').innerHTML = '';

      flush();
    });

    beforeEach(() => {
      fixture = TestBed.createComponent(TestMessageboxComponent);
    });

    it('with use type', () => {
      openMessagebox('confirm');

      openMessagebox('info');

      openMessagebox('success');

      openMessagebox('warning');

      openMessagebox('error');

      openMessagebox('danger');
    });

    it('with lvClass', () => {
      const cb = (): void => {
        expect(getMessageBox().className).toContain(CUSTOM_MESSAGE_BOX_CLASS);
      };

      openMessagebox('custom', cb);
    });

    it('with default width', () => {
      const cb = (): void => {
        const panel = document.querySelector('.lv-modal-panel') as any;
        expect(panel.style['width']).toBe('360px');
      };

      openMessagebox('confirm', cb);
    });
  });
});
